package io.renren.modules.nfy.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.query.QueryTool;
import io.renren.common.utils.ExcelUtils;
import io.renren.common.utils.Pages;
import io.renren.common.utils.Query;
import io.renren.common.utils.R;
import io.renren.modules.file.config.FileProperties;
import io.renren.modules.file.entity.FileEntity;
import io.renren.modules.file.service.FileService;
import io.renren.modules.file.service.FileUploadService;
import io.renren.modules.nfy.dao.ProductDao;
import io.renren.modules.nfy.entity.ProductEntity;
import io.renren.modules.nfy.service.ProductService;
import io.renren.modules.nfy.util.FileListUtil;
import io.renren.modules.sys.entity.SysUserEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


@Service("productService")
public class ProductServiceImpl extends ServiceImpl<ProductDao, ProductEntity> implements ProductService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    public static final String BASE_CODE = "NFY36028";


    @Value("${file.upload-dir}")
    private String uploadDir;

    @Autowired
    private FileUploadService fileUploadService;

    @Autowired
    private FileService fileService;

    @Override
    public Pages<ProductEntity> queryPage(ProductEntity Product) {
        QueryWrapper<ProductEntity> qw = new QueryWrapper<>();
        QueryTool.condition(qw, Product);

        IPage<ProductEntity> page = this.page(
                new Query<ProductEntity>().getPage(Product),
                qw
        );

        return new Pages<ProductEntity>(page);
    }

    public List<ProductEntity> listAll(ProductEntity Product) {
        QueryWrapper<ProductEntity> qw = new QueryWrapper<>();
        QueryTool.condition(qw, Product);
        return this.list(qw);
    }

    @Override
    public void doSave(ProductEntity product) {
        Date now = new Date();
        String dateStr = sdf.format(now);
        Integer max = getMaxCode();
        max += 1;
        String code = NumberUtil.decimalFormat("000", max);
        String traceCode = BASE_CODE + dateStr + code;

        product.setNum(max);
        product.setTraceCode(traceCode);
        save(product);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void uploadExcel(MultipartFile file, SysUserEntity user) throws Exception {
        Map<Integer, Map<Integer, Object>> map = ExcelUtils.readExcelContentz(file);
        Iterator<Map.Entry<Integer, Map<Integer, Object>>> it = map.entrySet().iterator();

        ProductEntity temp = null;
        Date now = new Date();
        String dateStr = sdf.format(now);


        while (it.hasNext()) {
            Map.Entry<Integer, Map<Integer, Object>> entry = it.next();
            Map<Integer, Object> inner = entry.getValue();

            String code = Convert.toStr(inner.get(0));
            String name = Convert.toStr(inner.get(1));
            String productYear = Convert.toStr(inner.get(2));
            String makeWay = Convert.toStr(inner.get(3));

            temp = selectOne("code", code);
            // 不存在则新增
            if (temp == null) {
                Integer max = getMaxCode();
                max += 1;
                String maxCode = NumberUtil.decimalFormat("000", max);
                String traceCode = BASE_CODE + dateStr + maxCode;

                temp = new ProductEntity();
                temp.setCode(code);
                temp.setName(name);
                temp.setProductYear(productYear);
                temp.setMakeWay(makeWay);
                temp.setTraceCode(traceCode);
                temp.setNum(max);
                temp.setCreateUser(user.getUsername());
                temp.setCreateTime(now);


                save(temp);
            } else {
                // 存在直接更新
                temp.setUpdateUser(user.getUsername());
                temp.setUpdateTime(now);
                temp.setName(name);
                temp.setProductYear(productYear);
                temp.setMakeWay(makeWay);

                updateById(temp);
            }
        }
    }


    public Integer getMaxCode() {
        Integer max = baseMapper.selectMaxNum();
        if (max == null) {
            max = 0;
        }
        return max;
    }


    /**
     * 保存单个文件
     *
     * @param file
     * @param xtlx
     */
    @Override
    public String saveImage(MultipartFile file, String xtlx) {
        String fullName = file.getOriginalFilename();
        int index = fullName.lastIndexOf(".");

        String code = fullName.substring(0, index);

        ProductEntity productEntity = selectOne("code", code);
        if (productEntity == null) {
            return "找不到编码为：" + code + "的商品";
        }

        FileEntity fileEntity = fileUploadService.storeFile(file, xtlx);
        String downPath = fileEntity.getUrl();
        productEntity.setAttachPath(downPath);

        updateById(productEntity);

        return null;
    }

    /**
     * 上传zip
     *
     * @param file
     * @param xtlx
     * @return
     */
    @Override
    public String uploadZip(MultipartFile file, String xtlx) {
        System.out.println("uploadDir:" + uploadDir);
        Date date1 = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String currentTime = xtlx + File.separatorChar + dateFormat.format(date1);

        String oriFileName = StringUtils.cleanPath(file.getOriginalFilename());
        String _fileName = oriFileName.substring(0, oriFileName.lastIndexOf("."));
        System.out.println("_fileName:" + _fileName);
        String suffix = oriFileName.substring(oriFileName.lastIndexOf(".") + 1);
        String fileName = _fileName + "_" + date1.getTime() + "." + suffix;

        // 目录
        String dir = uploadDir + File.separatorChar + currentTime;
        // 绝对路径
        String absPath = dir + File.separatorChar + fileName;
        // 解压目录路径
        String extractPath = dir + File.separatorChar + _fileName + "_" + date1.getTime();

        logger.error("dir:" + dir);
        logger.error("absPath:" + absPath);

        // 目标文件
        File destFile = new File(absPath);
        // 目标目录
        File fileDirectory = new File(dir);
        // 解压后目录
        File extractFolder = new File(extractPath);
        //当上传路径不存在时，生成上传路径
        if (!fileDirectory.exists()) {
            fileDirectory.mkdirs();
        }

        //  调用上面【处理压缩包文件方法】得到返回结果(解压到当前文件夹)
        R zipResult = dealZip(file, destFile, extractFolder);
        // 上传压缩包失败
        if(!zipResult.get("code").equals(0)) {
            return zipResult.get("msg").toString();
        }

        List<File> files = (List<File>) zipResult.get("files");

        ProductEntity productEntity = null;

        for(File file1 : files) {
            String path = file1.getPath();
            int startIndex = path.indexOf(xtlx);
            String relatePath = File.separator + path.substring(startIndex);
            String fname = FileListUtil.getFileName(file1);
            String _suffix = FileListUtil.getFileSuffix(file1);

            productEntity = selectOne("code", fname);
            if(productEntity != null) {
                FileEntity fileEntity = new FileEntity();
                fileEntity.setFileName(file1.getName());
                fileEntity.setOriFileName(file1.getName());
                fileEntity.setSuffix(_suffix);
                fileEntity.setXtlx(xtlx);
                fileEntity.setUrl(relatePath);
                fileEntity.setCreateTime(date1);
                fileEntity.setRelateId(Integer.valueOf(productEntity.getId().toString()));

                fileService.save(fileEntity);

                String downPath = fileEntity.getUrl();

                productEntity.setAttachPath(downPath);
                updateById(productEntity);
            }

        }

        return null;
    }

    private R dealZip(MultipartFile zipFile, File destFile, File extractFolder) {
        if (!extractFolder.exists()) {
        //  不存在就创建
            extractFolder.mkdirs();
        }

        try {
            //  步骤1、把上传的压缩包文件保存到指定压缩包路径
            zipFile.transferTo(destFile);
        } catch (IOException e) {
            e.printStackTrace();
            return R.error(e.getMessage());
        }

        //  步骤2、调用Hutool的ZipUtil压缩工具类的unzip方法来进行对压缩包文件的解压，解压到指定目录
        ZipUtil.unzip(destFile, extractFolder);

        // 解压缩完删除原文件（可不删）
        destFile.delete();

        //步骤3、获取解压后目录下所有的文件
//        File[] images = FileUtil.ls(extractFolder.getAbsolutePath());
        List<File> files = FileListUtil.getAllFile(extractFolder);

        //这边对获取到的文件数组进行判空校验
        if (files == null || files.size() == 0) {
            extractFolder.delete();
            return R.error("上传失败，压缩包为空");
        }

        return R.ok().put("files", files);
    }
}